package mtt.us.service;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import net.sf.hibernate4gwt.core.HibernateBeanManager;
import net.sf.hibernate4gwt.core.beanlib.mapper.DirectoryClassMapper;
import net.sf.hibernate4gwt.gwt.HibernateRemoteService;
import net.sf.hibernate4gwt.pojo.gwt.LazyGwtPojo;
import mtt.us.client.services.StundenplanService;

public class StundenplanServiceImpl extends HibernateRemoteService implements
		StundenplanService {

	/**
	 * enthält den persistensUnit-Name
	 */
	private static String persistensUnitName = "mttusPU";

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = -1028570026596602804L;

	/**
	 * 
	 */
	private static EntityManagerFactory entityManagerFactory;

	static {
		/*
		 * Factory erstellen und HibernateBeanManager initialisieren
		 */
		entityManagerFactory = Persistence
				.createEntityManagerFactory(persistensUnitName);
		HibernateBeanManager.getInstance().setEntityManagerFactory(
				entityManagerFactory);

		/*
		 * DirectoryMapper initialisieren
		 */
		DirectoryClassMapper cloneMapper = new DirectoryClassMapper();

		cloneMapper.setRootDomainPackage("mtt.us.domain");
		cloneMapper.setRootClonePackage("mtt.us.dto");
		cloneMapper.setCloneSuffix("DTO");

		HibernateBeanManager.getInstance().setClassMapper(cloneMapper);
	}

	public void deletePojo(LazyGwtPojo pojo) {
		// TODO Auto-generated method stub

	}

	@SuppressWarnings("unchecked")
	public List<LazyGwtPojo> getListPojos(String className, String[] properties) {

		EntityManager entityManager = entityManagerFactory
				.createEntityManager();
		
				
		entityManager.getTransaction().begin();

		/*
		 * Liste laden
		 */
		List listEntitys = entityManager.createQuery("FROM " + className)
				.getResultList();

		entityManager.getTransaction().commit();
		
		/*
		 * Properties laden
		 */
		if  ((properties != null )&& (properties.length > 0)) {
			loadProperties(listEntitys, properties);
		}

		return (List<LazyGwtPojo>) clone(listEntitys);

	}

	/**
	 * lädt alle benötigten Properties 
	 * 
	 * @param listEntitys
	 * @param properties
	 */
	@SuppressWarnings("unchecked")
	private void loadProperties(List listEntitys, String[] properties) {
		
		Iterator iterator = listEntitys.iterator();
		
		while (iterator.hasNext()) {
			Object object = (Object) iterator.next();
			loadPropertie(object, properties);
		}
		
	}

	/**
	 * lädt alle Properties des Objects 
	 * 
	 * @param object
	 * @param properties
	 */
	private void loadPropertie(Object object, String[] properties) {
		
		for (String propertieName : properties) {
			getPropertyValue(object, propertieName);
		}
		
	}

	public void persistPojo(LazyGwtPojo pojo) {
		// TODO Auto-generated method stub

	}

	public void updatePojo(LazyGwtPojo pojo) {
		// TODO Auto-generated method stub

	}

	private static Object getPropertyValue(Object obj, String propertyName) {
		try {
			
			Class<? extends Object> objClass = obj.getClass();

			String pn = propertyName.substring(0, 1).toUpperCase()
					+ propertyName.substring(1);

			Method method;

			try {
				
				method = objClass.getMethod("get" + pn);
				
			} catch (Exception exGet) {
				
				method = objClass.getMethod("is" + pn);
				
			}

			Object value = method.invoke(obj, (Object[]) null);

			return value;
			
		} catch (Exception e) {
			
			throw new RuntimeException("Property not found " + propertyName, e);
			
		}
	}

}
